package io.openkunlun.scaladsl.server

import akka.actor.ActorSystem
import akka.grpc.scaladsl.Metadata
import akka.util.Timeout
import com.typesafe.config.ConfigFactory
import io.openkunlun.scaladsl.serialization.SerializationTestProtocol._
import io.openkunlun.scaladsl.serialization.{DaprObjectSerialization, JsonDelegateSerialization}
import org.json4s.ext.EnumNameSerializer

import java.security.cert.CertificateFactory
import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Future}
import scala.io.Source

/**
 * @author ericxin.
 */
object DaprServerBootstrapSpec1 extends App {

  val conf = ConfigFactory.parseString("akka.http.server.preview.enable-http2 = on")
    .withFallback(ConfigFactory.defaultApplication())

  implicit val system = ActorSystem("DaprAppServerSpec", conf)
  implicit val ec = system.dispatcher
  val ser = JsonDelegateSerialization(system)
  ser.addFormat(new EnumNameSerializer(Gender))

  val server = new DaprServer(system)
  val invocationHandler = new InvocationService[Format, Format] {
    override val serialization: DaprObjectSerialization = ser
    implicit val deadline: Timeout = 30.seconds

    override def handle(req: InvocationRequest[Format], metadata: Metadata)(implicit ec: ExecutionContext, timeout: Timeout): Future[InvocationResponse[Format]] = {
      req.data match {
        case c: SerializationDto1 =>
          println("AbstractDaprInvocationHandler: " + c)
          Future.successful(InvocationResponse(SerializationDto3(key = " - 1", value = " - 1")))
        case _ =>
          Future.successful(InvocationResponse(SerializationDto2(key = " - 1", value = " - 1")))
      }
    }

    override val methods: Seq[String] = Seq(SerializationDto1.getClass.toString, SerializationDto2.getClass.toString, SerializationDto3.getClass.toString)
  }
  server.addHandler(invocationHandler)

  val bindingHandler = new BindingService[SerializationDto1, SerializationDto2] {
    override val serialization: DaprObjectSerialization = ser
    implicit val deadline: Timeout = 30.seconds

    override def handle(req: BindingRequest[SerializationDto1], metadata: Metadata)(implicit ec: ExecutionContext, timeout: Timeout): Future[BindingResponse[SerializationDto2]] = {
      println("AbstractDaprBindingHandler: " + req.data)
      Future.successful(BindingResponse(SerializationDto2(key = req.data.key + " - 1", value = req.data.value + " - 1")))
    }


    override val name: String = SerializationDto1.getClass.toString
  }
  server.addHandler(bindingHandler)

  val p12 = Source.fromInputStream(getClass.getClassLoader.getResourceAsStream("certs/server1.key")).mkString
  val certificate = getClass.getClassLoader.getResourceAsStream("certs/server1.pem")

  val fact = CertificateFactory.getInstance("X.509")
  val keyCertChain = fact.generateCertificate(certificate)

  //  server.runHttps("127.0.0.1", 8080, p12, keyCertChain.asInstanceOf[X509Certificate])
  server.start("172.16.1.76", 8080)
}
